package utils

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"runtime"
)

func DirectoryCreator(directories ...string) error {
	for _, d := range directories {
		err := os.MkdirAll(d, os.ModePerm)
		if err != nil {
			return err
		}
	}
	return nil
}

func PathExists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}

type DownloadOptions struct {
	OnlinePath string
	LocalPath  string
	FileName   string
}
type Reader struct {
	io.Reader
	Total   int64
	Current int64
}

func (r *Reader) Read(p []byte) (n int, err error) {
	n, err = r.Reader.Read(p)
	r.Current += int64(n)
	fmt.Printf("\r进度 %.2f%%", float64(r.Current*10000/r.Total)/100)
	return
}

//	func DownloadFile(options DownloadOptions, mode os.FileMode) {
//		res, err := http.Get(options.OnlinePath)
//		if err != nil {
//			panic(err)
//		}
//		defer res.Body.Close()
//		f, _ := os.Create(options.LocalPath)
//		defer f.Close()
//		reader := &Reader{
//			Reader: res.Body,
//			Total:  res.ContentLength,
//		}
//		io.Copy(f, reader)
//	}
func DownloadFile(options DownloadOptions, mode os.FileMode) error {

	out, err := os.OpenFile(options.LocalPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, mode)
	if err != nil {
		return err
	}

	resp, err := http.Get(options.OnlinePath)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	if _, err = io.Copy(out, resp.Body); err != nil {
		return err
	}

	err = out.Close()
	if err != nil {
		return err
	} // Close file to rename
	return nil
}

// getUserOS returns the users OS as well as the file extension of executables for said OS
func GetUserOS() (string, string) {
	var osBuild string
	var fileExt string

	switch goos := runtime.GOOS; goos {
	case "darwin":
		osBuild = "darwin"
		fileExt = ""
	case "linux":
		osBuild = "linux"
		fileExt = ""
	case "windows":
		osBuild = "windows"
		fileExt = ".exe"
	default:
		osBuild = "unsupported"
		fileExt = ""
	}

	return osBuild, fileExt
}
func VersionOrdinal(version string) string {
	// ISO/IEC 14651:2011
	const maxByte = 1<<8 - 1
	vo := make([]byte, 0, len(version)+8)
	j := -1
	for i := 0; i < len(version); i++ {
		b := version[i]
		if '0' > b || b > '9' {
			vo = append(vo, b)
			j = -1
			continue
		}
		if j == -1 {
			vo = append(vo, 0x00)
			j = len(vo) - 1
		}
		if vo[j] == 1 && vo[j+1] == '0' {
			vo[j+1] = b
			continue
		}
		if vo[j]+1 > maxByte {
			panic("VersionOrdinal: invalid version")
		}
		vo = append(vo, b)
		vo[j]++
	}
	return string(vo)
}

func VarsionDiff(v1 string, v2 string) string {
	a, b := VersionOrdinal(v1), VersionOrdinal(v2)
	result := ""
	switch {
	case a > b:
		result = ">"
	case a < b:
		result = "<"
	case a == b:
		result = "="
	}
	return result
}
